--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
meshchatx/src/backend/ringtone_manager.py 4bd787ccd70a459a02eececca3f942f0e64ec4ce (4bd787cc) Text, 2.41 KB
T8b949e# SPDX-License-Identifier: 0BSD
Tff7b72import T7ee787os
Tff7b72from T7ee787.T7ee787audio_codec Tff7b72import Te6edf3encode_audio_to_ogg_opus
Tff7b72def Td2a8ff_ringtone_profileTb4b4b4(Tb4b4b4)Tb4b4b4:
T8b949e"""Stereo 48 kHz Opus audio profile for music-grade ringtones."""
Tff7b72from T7ee787LXSTT7ee787.T7ee787Codecs Tff7b72import Te6edf3Opus
Tff7b72return Te6edf3OpusTff7b72.Td2a8ffPROFILE_AUDIO_MAX
Tff7b72class T56d364RingtoneManagerTb4b4b4:
Tff7b72def Tff7b72__init__Tb4b4b4(
Tff7b72selfTb4b4b4,
Te6edf3configTb4b4b4,
Te6edf3storage_dirTb4b4b4,
Tff7b72*Tb4b4b4,
Te6edf3asset_subdirTff7b72=Ta5d6ff"Ta5d6ffringtonesTa5d6ff"Tb4b4b4,
Te6edf3filename_prefixTff7b72=Ta5d6ff"Ta5d6ffringtoneTa5d6ff"Tb4b4b4,
Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffconfig Tff7b72= Te6edf3config
Tff7b72selfTff7b72.Td2a8ffasset_subdir Tff7b72= Te6edf3asset_subdir
Tff7b72selfTff7b72.Td2a8fffilename_prefix Tff7b72= Te6edf3filename_prefix
Tff7b72selfTff7b72.Td2a8ffstorage_dir Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3storage_dirTb4b4b4, Te6edf3asset_subdirTb4b4b4)
Te6edf3osTff7b72.Td2a8ffmakedirsTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstorage_dirTb4b4b4, Te6edf3exist_okTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72def Td2a8ffconvert_to_ringtoneTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3input_pathTb4b4b4, Te6edf3ringtone_idTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
T8b949e"""Decode input_path and re-encode it as an OGG/Opus ringtone.
Accepts any audio container miniaudio can decode (WAV, MP3, FLAC,
OGG/Vorbis) plus OGG/Opus via LXST. Encoded with the music
audio profile so trim edits preserve the original duration
and stereo image instead of being forced through the low-bitrate
voice profile. Returns the stored filename.
"""
Tff7b72import T7ee787secrets
Te6edf3filename Tff7b72= Ta5d6fffTa5d6ff"Tffd700{Tff7b72selfTff7b72.Td2a8fffilename_prefixTffd700}Ta5d6ff_Tffd700{Te6edf3secretsTff7b72.Td2a8fftoken_hexTb4b4b4(T79c0ff8Tb4b4b4)Tffd700}Ta5d6ff.opusTa5d6ff"
Te6edf3opus_path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstorage_dirTb4b4b4, Te6edf3filenameTb4b4b4)
Te6edf3encode_audio_to_ogg_opusTb4b4b4(Te6edf3input_pathTb4b4b4, Te6edf3opus_pathTb4b4b4, Te6edf3profileTff7b72=Te6edf3_ringtone_profileTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72return Te6edf3filename
Tff7b72def Td2a8ffremove_ringtoneTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3filenameTb4b4b4)Tb4b4b4:
Te6edf3safe Tff7b72= Tff7b72selfTff7b72.Td2a8ff_safe_storage_filenameTb4b4b4(Te6edf3filenameTb4b4b4)
Tff7b72if Te6edf3safe Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72False
Te6edf3opus_path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstorage_dirTb4b4b4, Te6edf3safeTb4b4b4)
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffexistsTb4b4b4(Te6edf3opus_pathTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3opus_pathTb4b4b4)
Tff7b72return Tff7b72True
Tff7b72def Td2a8ffget_ringtone_pathTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3filenameTb4b4b4)Tb4b4b4:
Te6edf3safe Tff7b72= Tff7b72selfTff7b72.Td2a8ff_safe_storage_filenameTb4b4b4(Te6edf3filenameTb4b4b4)
Tff7b72if Te6edf3safe Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72None
Te6edf3path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffrealpathTb4b4b4(Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstorage_dirTb4b4b4, Te6edf3safeTb4b4b4)Tb4b4b4)
Te6edf3root Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffrealpathTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstorage_dirTb4b4b4)
Tff7b72if Te6edf3path Tff7b72!= Te6edf3root Tff7b72and Tff7b72not Te6edf3pathTff7b72.Td2a8ffstartswithTb4b4b4(Te6edf3root Tff7b72+ Te6edf3osTff7b72.Td2a8ffsepTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72None
Tff7b72return Te6edf3path
Tff7b72def Td2a8ff_safe_storage_filenameTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3filenameTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3filenameTb4b4b4, Tffa657strTb4b4b4) Tff7b72or Tff7b72not Te6edf3filename Tff7b72or Ta5d6ff"Tffea00\x00Ta5d6ff" Tff7b72in Te6edf3filenameTb4b4b4:
Tff7b72return Tff7b72None
Te6edf3base Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffbasenameTb4b4b4(Te6edf3filenameTff7b72.Td2a8ffreplaceTb4b4b4(Ta5d6ff"Tffea00\\Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff/Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3base Tff7b72or Te6edf3base Tff7b72in Tb4b4b4{Ta5d6ff"Ta5d6ff.Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff..Ta5d6ff"Tb4b4b4} Tff7b72or Ta5d6ff"Ta5d6ff:Ta5d6ff" Tff7b72in Te6edf3baseTb4b4b4:
Tff7b72return Tff7b72None
Tff7b72return Te6edf3base
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────